package file

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/xuri/excelize/v2"
	"iot-base/auth/model"
	"iot-base/auth/svc"
	"iot-base/auth/types"
	"iot-base/auth/utils"
	"os"
	"path"
	"strconv"
	"strings"
	"time"
)

var confPath = "./static/conf/"

func GetConf(c *gin.Context) {
	resp := types.NewResult(c)
	var req types.ReqGetConf
	err := c.ShouldBind(&req)
	if err != nil {
		resp.ErrorCode(types.ParamsError, err.Error())
		return
	}
	pathFile := confPath + req.FileName
	_, err = os.Stat(pathFile)
	if err != nil {
		resp.Success(gin.H{})
		return
	}
	file, err := os.Open(pathFile)
	if err != nil {
		resp.Success(gin.H{})
		return
	}
	defer file.Close()
	dec := json.NewDecoder(file)
	confData := make([]map[string]interface{}, 0, 2)
	for {
		var kvJson map[string]interface{}
		if err := dec.Decode(&kvJson); err != nil {
			break
		}
		confData = append(confData, kvJson)
	}
	resp.Success(gin.H{"data": confData})
	return
}

func SetConf(c *gin.Context) {
	resp := types.NewResult(c)
	var req types.ReqSetConf
	err := c.ShouldBind(&req)
	if err != nil {
		resp.ErrorCode(types.ParamsError, err.Error())
		return
	}

	_, err = os.Stat(confPath)
	if os.IsNotExist(err) {
		err = os.MkdirAll(confPath, 0644)
		if err != nil {
			resp.ErrorCode(types.ParamsError, err.Error())
			return
		}
	}

	pathFile := confPath + req.FileName
	file, err := os.OpenFile(pathFile, os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		resp.ErrorCode(types.ParamsError, err.Error())
		return
	}

	defer file.Close()
	enc := json.NewEncoder(file)
	for _, v := range req.Context {
		err = enc.Encode(v)
		if err != nil {
			resp.ErrorCode(types.ParamsError, err.Error())
			return
		}
	}
	resp.Success(gin.H{})
	return
}

type AuthRule struct {
	ID         string `test:"" json:"ID"`
	Type       int    `test:":1为菜单,2为权限节点" json:"type"`
	Pid        string `test:"comment:父ID" json:"pid"`
	Title      string `test:"comment:规则标题" json:"title"`
	AuthRule   string `test:"comment: 权限规则" json:"auth_rule"`
	RouterName string `test:"comment: 前端路由昵称" json:"router_name"`
	Path       string `test:"comment: 前端的组件路径" json:"path"`
	Method     string `test:"comment: 请求方法" json:"method"`
	Icon       string `test:"comment: 菜单图标路径或class名称" json:"icon"`
	Weigh      int    `test:"comment:权重" json:"weigh"`
	AuthCode   string `test:"comment:权限编码，用于前端控制按钮/tab标签是否显示" json:"auth_code"`
	Remark     string `test:"comment:备注字段" json:"remark"`
	Extend     string `test:"comment:扩展字段" json:"extend"`
	RouterPath string `test:"comment: 前端路由" json:"router_path"`
	KeepAlive  bool   `json:"keep_alive"`
}

func ExportMenu(c *gin.Context) {
	key := c.Query("key")
	if key != "kdl" {
		c.JSON(200, gin.H{"err": "err"})
		return
	}
	list, err := svc.Dao.TAuthRule.FindRuleAll()
	if err != nil {
		c.JSON(200, gin.H{"err": err})
		return
	}
	var res = make([]interface{}, 0, len(list))
	for _, v := range list {
		temp := AuthRule{
			ID:         strconv.FormatInt(v.ID, 10),
			Type:       v.Type,
			Pid:        strconv.FormatInt(v.Pid, 10),
			Title:      v.Title,
			AuthRule:   v.AuthRule,
			RouterName: v.RouterName,
			Path:       v.Path,
			Method:     v.Method,
			Icon:       v.Icon,
			Weigh:      v.Weigh,
			AuthCode:   v.AuthCode,
			Remark:     v.Remark,
			Extend:     v.Extend,
			RouterPath: v.RouterPath,
			KeepAlive:  v.KeepAlive,
		}
		res = append(res, temp)
	}
	title := []string{`ID`, `类型1为菜单,2为权限节点`, `父ID`, `规则标题`, "权限规则", "前端路由昵称", "前端的组件路径", "请求方法", "菜单图标路径或class名称", "权重", "权限编码，用于前端控制按钮/tab标签是否显示", "备注字段", "扩展字段", "前端路由", "keep_alive"}
	utils.ExportExcelByStruct(c, title, res, "rule", "Sheet1")
	return
}

func ImportMenu(c *gin.Context) {
	resp := types.NewResult(c)
	f, err := c.FormFile("xlsx")
	// 图片大小不能超过 2M
	if (float64(f.Size) / 1024) > 2048 {
		resp.ErrorCode(types.UploadError, "文件大小不能超过2M")
		return
	}
	if err != nil {
		resp.ErrorCode(types.UploadError, "")
		return
	} else {
		fileExt := strings.ToLower(path.Ext(f.Filename))
		if fileExt != ".xlsx" {
			resp.ErrorCode(types.UploadError, "上传失败!")
			return
		}
		xFile, err := f.Open()
		if err != nil {
			resp.ErrorCode(types.UploadError, err.Error())
			return
		}
		xlsx, err := excelize.OpenReader(xFile)
		if err != nil {
			resp.ErrorCode(types.UploadError, err.Error())
			return
		}
		rows, err := xlsx.GetRows("Sheet1")
		if err != nil {
			resp.ErrorCode(types.UploadError, err.Error())
			return
		}
		if len(rows) == 0 {
			resp.ErrorCode(types.UploadError, "文件格式错误")
			return
		}
		datas := make([]model.AuthRule, 0, len(rows))
		for v, row := range rows {
			if v == 0 {
				continue
			}
			if len(row) < 15 {
				resp.ErrorCode(types.UploadError, "文件格式错误")
				return
			}
			id, _ := strconv.ParseInt(row[0], 10, 64)
			stype, _ := strconv.Atoi(row[1])
			pid, _ := strconv.ParseInt(row[2], 10, 64)
			weigh, _ := strconv.Atoi(row[9])
			keepAlive, _ := strconv.ParseBool(row[14])
			temp := model.AuthRule{
				Type:       stype,
				Pid:        pid,
				Title:      row[3],
				AuthRule:   row[4],
				RouterName: row[5],
				Path:       row[6],
				Method:     row[7],
				Icon:       row[8],
				Weigh:      weigh,
				AuthCode:   row[10],
				Remark:     row[11],
				Extend:     row[12],
				RouterPath: row[13],
				KeepAlive:  keepAlive,
			}
			temp.ID = id
			temp.CreatedAt = time.Now()
			temp.UpdatedAt = time.Now()
			datas = append(datas, temp)
		}
		db := svc.Dao.GetDb()
		tx := db.Begin()
		err = tx.Model(&model.AuthRule{}).Where("1=1").Delete(&model.AuthRule{}).Error
		if err != nil {
			tx.Rollback()
			resp.ErrorCode(types.UploadError, err.Error())
			return
		}
		err = tx.Model(&model.AuthRule{}).CreateInBatches(&datas, len(datas)).Error
		if err != nil {
			tx.Rollback()
			resp.ErrorCode(types.UploadError, err.Error())
			return
		}
		tx.Commit()
		resp.Success(gin.H{"成功": "成功"})
	}

}
